package org.computate.controller.filter.item.Upload;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.computate.model.dao.ComputateDao;
import org.computate.model.dao.PhotoDao;
import org.computate.model.dao.UploadDao;
import org.computate.model.dao.WebAlbumDao;
import org.computate.model.item.Model;
import org.computate.model.item.Photo;
import org.computate.model.item.Upload;
import org.computate.model.item.WebAlbum;
import org.computate.tool.ModelTool;

import com.google.gdata.client.photos.PicasawebService;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.media.MediaByteArraySource;
import com.google.gdata.data.photos.AlbumEntry;
import com.google.gdata.data.photos.PhotoEntry;
import com.google.gdata.data.photos.UserFeed;
import com.google.gdata.util.ServiceException;
import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class FilterUploadProcessPhoto implements Filter {
	
	@Inject private ModelTool modelTool;

	@Inject private WebAlbumDao webAlbumDao;
	@Inject private UploadDao uploadDao;
	@Inject private PhotoDao photoDao;
	
	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		String idParam = httpRequest.getParameter("id");
		Long id = null;
		
		try {
			id = Long.parseLong(idParam);
			
			String username = "content@toshmd.com";
			PicasawebService service = new PicasawebService("HomePagePicasawebService");
			String filename = null;
			String contentType = null;
			String message = "Your image was processed successfully.";
			Model uploadInstance = Upload.class.newInstance();
			
			Upload upload = uploadDao.get(id, uploadInstance.getGetLevels());

			if(upload == null) {
				throw new RuntimeException("The Upload model with id " + id + " is not available yet.");
			}
			else {
				Long classId = upload.getItemId();
				String itemModelName = upload.getItemName();
				
				ComputateDao<?> currentDao = modelTool.getDao(itemModelName);
				try {
					Class<?> itemClass = modelTool.getItemClass(itemModelName);
					Model newInstance = (Model)itemClass.newInstance();
					Model item = (Model)currentDao.get(classId, newInstance.getGetLevels());
					WebAlbum webAlbum = (WebAlbum)webAlbumDao.ofy().query(WebAlbum.class).filter("forModel", itemModelName + "_" + classId).limit(1).get();
					
					contentType = upload.getContentType();
					filename = upload.getName();
					if(item != null) {
						String itemName = item.getName();
						URL feedUrl = new URL("https://picasaweb.google.com/data/feed/api/user/" + URLEncoder.encode(username, "UTF-8") + "?kind=album");
						
						service.setUserCredentials(username, "9poGm3UI");
						service.setConnectTimeout(2000);
						service.setReadTimeout(600000);
						if(webAlbum == null) {
							UserFeed userFeed = service.getFeed(feedUrl, UserFeed.class);
							
							for(AlbumEntry album : userFeed.getAlbumEntries()) {
								if((item.isPhotosPermitted() || item.isPhotoPermitted()) && album.getTitle().getPlainText().equals(itemName)) {
									String feed = "https://picasaweb.google.com/data/feed/api/user/" + URLEncoder.encode(username, "UTF-8") + "/albumid/" + URLEncoder.encode(album.getGphotoId(), "UTF-8");
									
									webAlbum = new WebAlbum();
									webAlbum.setName(itemName);
									webAlbum.setFeed(feed);
									webAlbum.setForModel(itemModelName + "_" + classId);
									webAlbumDao.put(webAlbum);
									break;
								}
								if(album.getTitle().getPlainText().equals(itemModelName)) {
									String feed = "https://picasaweb.google.com/data/feed/api/user/" + URLEncoder.encode(username, "UTF-8") + "/albumid/" + URLEncoder.encode(album.getGphotoId(), "UTF-8");
									
									webAlbum = new WebAlbum();
									webAlbum.setName(itemModelName);
									webAlbum.setFeed(feed);
									webAlbum.setForModel(itemModelName);
									webAlbumDao.put(webAlbum);
									break;
								}
							}
						}
						if(webAlbum == null) {
							AlbumEntry album = new AlbumEntry();
							String albumName = null;
							
							if((item.isPhotosPermitted() || item.isPhotoPermitted()) && !StringUtils.isEmpty(itemName))
								albumName = itemName;
							else
								albumName = itemModelName;
							album.setTitle(new PlainTextConstruct(albumName));
							album = service.insert(feedUrl, album);
							
							String feed = "https://picasaweb.google.com/data/feed/api/user/" + URLEncoder.encode(username, "UTF-8") + "/albumid/" + URLEncoder.encode(album.getGphotoId(), "UTF-8");
							webAlbum = new WebAlbum();
							webAlbum.setName(albumName);
							webAlbum.setFeed(feed);
							webAlbum.setForModel(itemModelName);
							webAlbumDao.put(webAlbum);
						}
						if(webAlbum != null) {
							URL albumPostUrl = new URL(webAlbum.getFeed());
							byte[] bytes = upload.getImage().getBytes();
							Long nextId = upload.getNextId();
							
							while(nextId != null) {
								upload = uploadDao.get(nextId, uploadInstance.getGetLevels());
								if(upload != null) {
									byte[] nextBytes = upload.getImage().getBytes();
									
									bytes = (byte[]) ArrayUtils.addAll(bytes, nextBytes);
									nextId = upload.getNextId();
								}
								else {
									throw new RuntimeException("Unable to find next Upload model");
								}
							}

							PhotoEntry myPhoto = new PhotoEntry();
							myPhoto.setTitle(new PlainTextConstruct(filename));
							myPhoto.setDescription(new PlainTextConstruct(""));
							myPhoto.setClient("");

							MediaByteArraySource myMedia = new MediaByteArraySource(bytes, contentType);
							myPhoto.setMediaSource(myMedia);

							PhotoEntry returnedPhoto = service.insert(albumPostUrl, myPhoto);
				    		Photo photo = new Photo();
				    		photo.setName(filename);
				    		String caption = returnedPhoto.getDescription().getPlainText();
				    		photo.setDescription(caption);
				    		photo.setItemId(classId);
				    		photo.setItemName(itemModelName);
				    		photo.setWidth(returnedPhoto.getWidth());
				    		photo.setHeight(returnedPhoto.getHeight());
				    		String uri = returnedPhoto.getMediaGroup().getContents().get(0).getUrl();
				    		
				    		photo.setUri(uri);
				    		photoDao.put(photo);
						}
					}
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (ServiceException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			httpRequest.setAttribute("root", message);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}

}
